﻿using DBUtil.MetaData;
using DotNetCommon.Extensions;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace DBUtil.Provider.MySql.MetaData
{
    /// <summary>
    /// MySql列
    /// </summary>
    public class MySqlColumn : Column
    {
        /// <summary>
        /// 列类型
        /// </summary>
        public EnumMySqlColumnType Type { set; get; }

        /// <summary>
        /// 数据类型
        /// </summary>
        public string DATA_TYPE { get; set; }

        public long? CHARACTER_MAXIMUM_LENGTH { get; set; }
        public long? CHARACTER_OCTET_LENGTH { get; set; }
        public long? NUMERIC_PRECISION { get; set; }
        public long? NUMERIC_SCALE { get; set; }
        public long? DATETIME_PRECISION { get; set; }

        /// <summary>
        /// 字符集名称
        /// </summary>
        public string CHARACTER_SET_NAME { get; set; }
        /// <summary>
        /// 排序规则
        /// </summary>
        public string COLLATION_NAME { get; set; }

        /// <summary>
        /// spatial类型的坐标系统
        /// </summary>
        public int? SRS_ID { get; set; }

        #region ConvertType 转换列类型
        internal void ConvertType()
        {
            var column = this;
            switch (DATA_TYPE)
            {
                //位类型
                case "bit": { column.Type = EnumMySqlColumnType.Bit; break; }

                //数字
                case "tinyint":
                    {
                        if (TypeString.Contains("unsigned")) column.Type = EnumMySqlColumnType.TinyIntUnSigned;
                        else column.Type = EnumMySqlColumnType.TinyInt;
                        break;
                    }
                case "smallint":
                    {
                        if (TypeString.Contains("unsigned")) column.Type = EnumMySqlColumnType.SmallIntUnSigned;
                        else column.Type = EnumMySqlColumnType.SmallInt;
                        break;
                    }
                case "mediumint":
                    {
                        if (TypeString.Contains("unsigned")) column.Type = EnumMySqlColumnType.MediumIntUnSigned;
                        else column.Type = EnumMySqlColumnType.MediumInt;
                        break;
                    }
                case "int":
                    {
                        if (TypeString.Contains("unsigned")) column.Type = EnumMySqlColumnType.IntUnSigned;
                        else column.Type = EnumMySqlColumnType.Int;
                        break;
                    }
                case "bigint":
                    {
                        if (TypeString.Contains("unsigned")) column.Type = EnumMySqlColumnType.BigIntUnSigned;
                        else column.Type = EnumMySqlColumnType.BigInt;
                        break;
                    }
                case "float": { column.Type = EnumMySqlColumnType.Float; break; }
                case "double": { column.Type = EnumMySqlColumnType.Double; break; }
                case "decimal": { column.Type = EnumMySqlColumnType.Decimal; break; }

                //字符串
                case "char": { column.Type = EnumMySqlColumnType.Char; break; }
                case "varchar": { column.Type = EnumMySqlColumnType.VarChar; break; }
                case "tinytext": { column.Type = EnumMySqlColumnType.TinyText; break; }
                case "text": { column.Type = EnumMySqlColumnType.Text; break; }
                case "mediumtext": { column.Type = EnumMySqlColumnType.MediumText; break; }
                case "longtext": { column.Type = EnumMySqlColumnType.LongText; break; }

                //二进制
                case "binay": { column.Type = EnumMySqlColumnType.Binary; break; }
                case "varbinary": { column.Type = EnumMySqlColumnType.VarBinary; break; }
                case "tinyblob": { column.Type = EnumMySqlColumnType.TinyBlob; break; }
                case "blob": { column.Type = EnumMySqlColumnType.Blob; break; }
                case "mediumblob": { column.Type = EnumMySqlColumnType.MediumBlob; break; }
                case "longblob": { column.Type = EnumMySqlColumnType.LongBlob; break; }

                //日期时间
                case "year": { column.Type = EnumMySqlColumnType.Year; break; }
                case "date": { column.Type = EnumMySqlColumnType.Date; break; }
                case "time": { column.Type = EnumMySqlColumnType.Time; break; }
                case "datetime": { column.Type = EnumMySqlColumnType.DateTime; break; }
                case "timestamp": { column.Type = EnumMySqlColumnType.TimeStamp; break; }

                //其他
                case "enum": { column.Type = EnumMySqlColumnType.Enum; break; }
                case "set": { column.Type = EnumMySqlColumnType.Set; break; }
                case "json": { column.Type = EnumMySqlColumnType.Json; break; }

                //spatial
                case "geometry": { column.Type = EnumMySqlColumnType.Geometry; break; }
                case "point": { column.Type = EnumMySqlColumnType.Point; break; }
                case "linestring": { column.Type = EnumMySqlColumnType.LineString; break; }
                case "polygon": { column.Type = EnumMySqlColumnType.Polygon; break; }
                case "geometrycollection": { column.Type = EnumMySqlColumnType.GeometryCollection; break; }
                case "multipoint": { column.Type = EnumMySqlColumnType.MultiPoint; break; }
                case "multilinestring": { column.Type = EnumMySqlColumnType.MultiLineString; break; }
                case "multipolygon": { column.Type = EnumMySqlColumnType.MultiPolygon; break; }
            }
            TypeNum = (int)column.Type;
        }
        #endregion

        public static EnumMySqlColumnType? ParseColumnType(string typeString)
        {
            if (typeString.IsNullOrEmptyOrWhiteSpace()) return null;
            typeString = typeString.ToLower().Trim();
            if (typeString.StartsWith("bit")) return EnumMySqlColumnType.Bit;

            if (typeString.StartsWith("tinyint"))
            {
                if (typeString.Contains("unsigned")) return EnumMySqlColumnType.TinyIntUnSigned;
                else return EnumMySqlColumnType.TinyInt;
            }
            if (typeString.StartsWith("smallint"))
            {
                if (typeString.Contains("unsigned")) return EnumMySqlColumnType.SmallIntUnSigned;
                else return EnumMySqlColumnType.SmallInt;
            }
            if (typeString.StartsWith("mediumint"))
            {
                if (typeString.Contains("unsigned")) return EnumMySqlColumnType.MediumIntUnSigned;
                else return EnumMySqlColumnType.MediumInt;
            }
            if (typeString.StartsWith("bigint"))
            {
                if (typeString.Contains("unsigned")) return EnumMySqlColumnType.BigIntUnSigned;
                else return EnumMySqlColumnType.BigInt;
            }
            if (typeString.StartsWith("int"))
            {
                if (typeString.Contains("unsigned")) return EnumMySqlColumnType.IntUnSigned;
                else return EnumMySqlColumnType.Int;
            }

            if (typeString.StartsWith("float")) return EnumMySqlColumnType.Float;
            if (typeString.StartsWith("double")) return EnumMySqlColumnType.Double;
            if (typeString.StartsWith("decimal")) return EnumMySqlColumnType.Decimal;

            if (typeString.StartsWith("char")) return EnumMySqlColumnType.Char;
            if (typeString.StartsWith("varchar")) return EnumMySqlColumnType.VarChar;
            if (typeString.StartsWith("tinytext")) return EnumMySqlColumnType.TinyText;
            if (typeString.StartsWith("text")) return EnumMySqlColumnType.Text;
            if (typeString.StartsWith("mediumtext")) return EnumMySqlColumnType.MediumInt;
            if (typeString.StartsWith("longtext")) return EnumMySqlColumnType.LongText;

            if (typeString.StartsWith("binary")) return EnumMySqlColumnType.Binary;
            if (typeString.StartsWith("varbinary")) return EnumMySqlColumnType.VarBinary;
            if (typeString.StartsWith("tinyblob")) return EnumMySqlColumnType.TinyBlob;
            if (typeString.StartsWith("blob")) return EnumMySqlColumnType.Blob;
            if (typeString.StartsWith("mediumblob")) return EnumMySqlColumnType.MediumBlob;
            if (typeString.StartsWith("longblob")) return EnumMySqlColumnType.LongBlob;

            if (typeString.StartsWith("year")) return EnumMySqlColumnType.Year;
            if (typeString.StartsWith("timestamp")) return EnumMySqlColumnType.TimeStamp;
            if (typeString.StartsWith("datetime")) return EnumMySqlColumnType.DateTime;
            if (typeString.StartsWith("date")) return EnumMySqlColumnType.Date;
            if (typeString.StartsWith("time")) return EnumMySqlColumnType.Time;

            if (typeString.StartsWith("enum")) return EnumMySqlColumnType.Enum;
            if (typeString.StartsWith("set")) return EnumMySqlColumnType.Set;
            if (typeString.StartsWith("json")) return EnumMySqlColumnType.Json;
            if (typeString.StartsWith("geometry")) return EnumMySqlColumnType.Geometry;
            if (typeString.StartsWith("point")) return EnumMySqlColumnType.Point;
            if (typeString.StartsWith("linestring")) return EnumMySqlColumnType.LineString;
            if (typeString.StartsWith("polygon")) return EnumMySqlColumnType.Polygon;
            if (typeString.StartsWith("geometrycollection")) return EnumMySqlColumnType.GeometryCollection;
            if (typeString.StartsWith("multipoint")) return EnumMySqlColumnType.MultiPoint;
            if (typeString.StartsWith("multilinestring")) return EnumMySqlColumnType.MultiLineString;
            if (typeString.StartsWith("multipolygon")) return EnumMySqlColumnType.MultiPolygon;

            return null;

        }
    }
}
